#include "string.h"
#include "math.h"
#ifndef __IO_H
#define __IO_H

#define acpi_native_int int
#define _AUPBND (sizeof(acpi_native_int) - 1)
#define _ADNBND (sizeof (acpi_native_int) - 1)
#define _bnd(X, bnd) (((sizeof(X)) + (bnd)) & (~(bnd)))
#define va_arg(ap, T) (*((T*) (((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))))
#define va_end(ap) ((void)0)
#define va_start(ap, A) ((void)((ap) = (((char *)&(A)) + (_bnd(A, _AUPBND)))))

typedef char *va_list;

int x = 0, y = 0;
void putchar(const char ch)
{
    *(char *)(0xb8000 + (++x) * 160 + (++y) * 2) = ch;
}
char getchar()
{
    // 读屏幕函数
}
int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}

#ifdef ALLOW_UNSAFE
size_t gets(char *str)
{
    for (size_t i = 0; i <= 4294967295; i++)
    {
        *(str + i) = getchar();
        if (*(str + i) == '\n' || *(str + i) == ' ')
        {
            *(str + i) = '\0';
            return i;
        }
    }
    return (size_t)-1;
}
#endif
void puts(const char *str)
{
    while (*str)
    {
        putchar(*str++);
    }
}
int printf(const char *str, ...)
{
    va_list ap;
    int val, r_val;
    char count, ch;
    char *s = NULL;
    int res = 0; // 返回值

    va_start(ap, str);   // 初始化ap
    while ('\0' != *str) // str为字符串,它的最后一个字符肯定是'\0'（字符串的结束符）
    {
        switch (*str)
        {
        case '%': // 发送参数
            str++;
            switch (*str)
            {
            case 'd': // 10进制输出
                val = va_arg(ap, int);
                r_val = val;
                count = 0;
                while (r_val)

                {
                    count++; // 整数的长度
                    r_val /= 10;
                }
                res += count;
                // 返回值长度增加
                r_val = val;
                while (count)
                {
                    ch = r_val / quickpow(10, count - 1);
                    r_val %= quickpow(10, count - 1);
                    putchar(ch + '0');
                    // 数字到字符的转换
                    count--;
                }
                break;
            case 'x': // 16进制输出
                val = va_arg(ap, int);
                r_val = val;
                count = 0;
                while (r_val)

                {
                    count++; // 整数的长度
                    r_val /= 16;
                }
                res += count;
                // 返回值长度增加
                r_val = val;
                while (count)
                {
                    ch = r_val / quickpow(16, count - 1);
                    r_val %= quickpow(16, count - 1);
                    if (ch <= 9)
                        putchar(ch + '0');
                    // 数字到字符的转换
                    else
                        putchar(ch - 10 + 'a');
                    count--;
                }
                break;
            case 's': // 发送字符串
                s = va_arg(ap, char *);
                puts(s);
                // 字符串,返回值为字符指针
                res += strlen(s);
                // 返回值长度增加
                break;
            case 'c':
                putchar((char)va_arg(ap, int)); // 大家猜为什么不写char，而要写int
                res += 1;
                break;
            default:;
            }
            break;
        case '\n':
            putchar('\n');
            res += 1;
            break;
        case '\r':
            putchar('\r');
            res += 1;
            break;

        default: // 显示原来的第一个参数的字符串(不是..里的参数o)
            putchar(*str);
            res += 1;
        }
        str++;
    }
    va_end(ap);
    return res;
}
#endif // __IO_H